// modbus_server.cpp
#include <iostream>
#include <memory>
#include <cstring>
#include <modbus.h>
#include <unistd.h>
#include <errno.h>

int main()
{
    modbus_t *ctx;
    uint16_t tab_reg[32] = {100, 200, 300}; // 模拟保持寄存器
    uint8_t tab_bit[8] = {1, 0, 1};         // 模拟线圈

    // 创建服务器
    ctx = modbus_new_tcp("127.0.0.1", 5020);
    if (ctx == NULL) {
        std::cerr << "无法创建 Modbus TCP 上下文\n";
        return -1;
    }
    
    modbus_set_debug(ctx, TRUE); // 启用调试输出

    // 绑定并监听
    int server_socket = modbus_tcp_listen(ctx, 1);
    if (server_socket == -1)
    {
        std::cerr << "监听失败: " << modbus_strerror(errno) << std::endl;
        modbus_free(ctx);
        return -1;
    }

    std::cout << "Modbus TCP 服务器已启动，等待连接...\n";

    while (true)
    {
        modbus_mapping_t *mapping = modbus_mapping_new(8, 8, 32, 32);
        if (mapping == NULL)
        {
            std::cerr << "无法分配映射: " << modbus_strerror(errno) << std::endl;
            modbus_free(ctx);
            break;
        }

        // 初始化寄存器
        for (int i = 0; i < 32; i++) {
            mapping->tab_registers[i] = 0;
        }
        memcpy(mapping->tab_registers, tab_reg, sizeof(tab_reg));
        
        for (int i = 0; i < 8; i++) {
            mapping->tab_bits[i] = 0;
        }
        memcpy(mapping->tab_bits, tab_bit, sizeof(tab_bit));

        int socket = modbus_tcp_accept(ctx, &server_socket);
        if (socket == -1) {
            std::cerr << "接受连接失败: " << modbus_strerror(errno) << std::endl;
            modbus_mapping_free(mapping);
            continue;
        }

        std::cout << "客户端已连接\n";

        while (true)
        {
            uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH];
            int rc = modbus_receive(ctx, query);
            if (rc > 0)
            {
                modbus_reply(ctx, query, rc, mapping);
            }
            else
            {
                if (rc == -1 && errno != ECONNRESET && errno != EPIPE) {
                    std::cerr << "接收数据失败: " << modbus_strerror(errno) << std::endl;
                }
                break;
            }
        }

        close(socket);
        modbus_mapping_free(mapping);
        std::cout << "客户端断开连接\n";
    }

    modbus_close(ctx);
    modbus_free(ctx);
    return 0;
}